1

实现原理

关键属性 border-radius(画圆) transform(scale放大) transition(平滑过渡)
获取鼠标位置,动态态画圆,延时放大,完成后移除元素

css 部分

按钮样式

.btn {
         width: 200px;
         height: 56px;
         line-height: 56px;
         background: #426fc5;
         color: #fff;
         border-radius: 5px;
         text-align: center;
         cursor: pointer;
         overflow: hidden;
       }

原始波纹样式

.waves-animation {
       position: absolute;
       border-radius: 50%;
       width: 25px;
       height: 25px;
       background: rgba(255, 255, 255, 0.3);
       transition: all 750ms ease-out;
       transform: scale(0);
   }

html 部分

<div class="btn">press me!</div>

js 部分

(function (root, factory, plugName) {
        if (typeof define === 'function' && define.amd) {
            define([], factory);
        } else if (typeof module === 'object' && module.exports) {
            module.exports = factory();
        } else {
            root[plugName] = factory();
        }
    })(self, function () {
        //合并函数
        var __assign = Object.assign || function (t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        }

        // 参数
        var __options = {
            selector: '.btn'
        }

        // 工具函数
        var __utils = {
            $: function (selector) {
                return document.querySelector(selector)
            }
        }

        // 核心
        function core(options) {
            this.params = __assign(__options, options)
            this.Element = __utils.$(this.params.selector)
            this.Element.addEventListener('click', this.showWaves.bind(this))
        }

        core.prototype = {
            showWaves: function (e) {
                var insertDiv = document.createElement('div')
                insertDiv.className =insertDiv.className + " waves-animation"
                this.Element.appendChild(insertDiv)

                var _mousePos = this.mousePos(e),
                    _offset = this.offset(this.Element),
                    startCss = {
                        left: _mousePos.x - _offset.left + 'px',
                        top: _mousePos.y - _offset.top + 'px',
                        opacity: 1
                    },
                    finishCss = {
                        left: _mousePos.x - _offset.left + 'px',
                        top: _mousePos.y - _offset.top + 'px',
                        opacity: 0
                    }
                startCss[this.prefixStyle('transform')] = 'scale(' + _offset.width / 25 + ')'
                finishCss[this.prefixStyle('transform')] = 'scale(' + _offset.width / 25 * 2 + ')'

                insertDiv.setAttribute("style", this.getStyle(startCss));
                setTimeout(function () {
                    insertDiv.setAttribute("style", this.getStyle(finishCss));
                    setTimeout(function () {
                        this.Element.removeChild(insertDiv)
                    }.bind(this), 750)
                }.bind(this), 100)
            },
            //点击位置
            mousePos: function (e) {
                return {
                    x: e.pageX,
                    y: e.pageY
                };
            },
            // 元素位置
            offset: function (element) {
                return {
                    top: element.getBoundingClientRect().top,
                    left: element.getBoundingClientRect().left,
                    width: element.getBoundingClientRect().width
                }
            },
            // 对象转化为css字符串
            getStyle: function (object) {
                var cssStr = ''
                for (var key in object) {
                    cssStr += key + ':' + object[key] + ';'
                }
                return cssStr
            },
            // 驼峰转连字符
            toCSSStr(str){
                return str.replace(/([A-Z])/g,"-$1").toLowerCase();
            },
            //js 添加浏览器兼容前缀
            prefixStyle(style) {
                var vendor = this.vendor()
                if (!vendor) {
                    return false
                }
                if (vendor === 'standard') {
                    return style
                }
                // return vendor + style.charAt(0).toUpperCase() + style.substr(1);
                return '-' + vendor + '-' + style;
            },
            // 获得浏览器前缀
            vendor: function () {
                var elementStyle = document.createElement('div').style;
                var transformNames = {
                    webkit: 'webkitTransform',
                    Moz: 'MozTransform',
                    O: 'OTransform',
                    ms: 'msTransform',
                    standard: 'transform'
                }
                for (var key in transformNames) {
                    if (elementStyle[transformNames[key]] !== 'undefined') {
                        return key
                    }
                }
                return false
            }
        }
        return core
    }, 'wavesBtn')
    new wavesBtn()

天翔
24 声望1 粉丝

码农一枚